iT邦幫忙

DAY 21
0

x86 android 設備與外部硬體溝通研究系列 第 21

x86 android 設備與外部硬體溝通研究 - Android USB ? (21/30)

  • 分享至 

  • xImage
  •  

昨天我們成功控制arduino 輸出 PWM 控制 LED ,今天我們要來嘗試從 arduino 把資料讀回來。

PIN 0 跟 PIN 7 我們都拿來接在可變電阻的 output pin 上,來試看看會發生什麼事吧

直接看 code 吧:

package com.example.test;

import java.io.IOException;

import org.shokai.firmata.ArduinoFirmata;
import org.shokai.firmata.ArduinoFirmataEventHandler;

import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.os.Bundle;
import android.os.CountDownTimer;
import android.os.Handler;
import android.support.v7.app.ActionBarActivity;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
import android.widget.SeekBar;
import android.widget.SeekBar.OnSeekBarChangeListener;

import com.MyTestLibrary.CountingSensorUpateRate;

public class MainActivity extends ActionBarActivity{

	private boolean timerHasStarted = false ;
	private boolean ArduinoBlink = false ;
	private Button startB;
	private TestCounting CountDownTimer;
	private TextView AccelX;
	private TextView AccelY;
	private TextView AccelZ;
	private TextView OrienX;
	private TextView OrienY;
	private TextView OrienZ;
	private SensorActivity MySensor;
	private TextView TimeView;
	private TextView ElapsedView;
	private TextView CountAccel,CountOrien;
	private TextView seekBarValue,Variable_resistor,Variable_resistor2;
	private long timeElapsed;
	private long startTime = 60*1000;
	private long interval = 1*100; // 0.1 sec. per time interval
	private CountingSensorUpateRate MyCountingSensorUpdateRate;
	private SeekBar PWMValue;
	private Handler handler;

	private ArduinoFirmata arduino;
	
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        startB = (Button) this.findViewById(R.id.button1);
        startB.setOnClickListener(new Button_Listener(this));
        AccelX = (TextView) this.findViewById(R.id.AccelX);
        AccelY = (TextView) this.findViewById(R.id.AccelY);
        AccelZ = (TextView) this.findViewById(R.id.AccelZ);
        OrienX = (TextView) this.findViewById(R.id.OrienX);
        OrienY = (TextView) this.findViewById(R.id.OrienY);
        OrienZ = (TextView) this.findViewById(R.id.OrienZ);
    	TimeView= (TextView) this.findViewById(R.id.timer);
		ElapsedView= (TextView) this.findViewById(R.id.timeElapsed);
        CountAccel = (TextView) this.findViewById(R.id.UpateRate_Accel);
        CountOrien = (TextView) this.findViewById(R.id.UpateRate_Orien);
        seekBarValue = (TextView) this.findViewById(R.id.seekBarValue);
        Variable_resistor = (TextView) this.findViewById(R.id.Variable_resistor);
        Variable_resistor2 = (TextView) this.findViewById(R.id.Variable_resistor2);
        PWMValue = (SeekBar) this.findViewById(R.id.seekBar1);
        handler = new Handler();
        
        
        CountDownTimer = new TestCounting (startTime,interval);
        MyCountingSensorUpdateRate = new CountingSensorUpateRate();

        MySensor = new SensorActivity();
        MySensor.onPause();

        this.arduino = new ArduinoFirmata(this);
        final ActionBarActivity self = this; // 下面這段是今天新增的,主要是設定 arduino firmata 物件發生錯誤時/中斷連線是該怎做
		arduino.setEventHandler(new ArduinoFirmataEventHandler() {
			public void onError(String errorMessage) {
			}

			public void onClose() {
				self.finish(); // 直接關閉 APP 
			}
		});

        PWMValue.setOnSeekBarChangeListener( new OnSeekBarChangeListener() { 
        	int progressValue = 0;

			@Override
			public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
				progressValue = progress;
				seekBarValue.setText(String.valueOf(progressValue));
				if(arduino.isOpen()){
					arduino.analogWrite(11, progressValue); // pinNumber, value(0~255)
				}	
			}

			@Override
			public void onStartTrackingTouch(SeekBar seekBar) {
				// TODO Auto-generated method stub
			}

			@Override
			public void onStopTrackingTouch(SeekBar seekBar) {
				// TODO Auto-generated method stub
				//seekBarValue.setText(String.valueOf(progressValue));
			}
        });
        // 建立 一個 THREAD 來讀arduino 資料
		Thread thread = new Thread(new Runnable() {
			public void run() {
				while (arduino.isOpen()) {
					try {
						Thread.sleep(100);
						handler.post(new Runnable() {
							public void run() {
								int analog_value = arduino.analogRead(0); // 要求讀回 PIN 0 的資料
								boolean digital_value = arduino.digitalRead(7); // 要求讀回 PIN 7 的資料
								Variable_resistor.setText("analogRead(0) = "+ String.valueOf(analog_value));
								Variable_resistor2.setText("digitalRead(7) = "+ String.valueOf(digital_value));
							}
						});
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				}
			}
		});
// 我們改為啟動 APP 時就自動嘗試連線 arduino , 如果找不到 arduino 就關閉 app
		try {
			arduino.connect();
			arduino.pinMode(7, ArduinoFirmata.INPUT); // 設定這兩個 PIN 為 input mode
			arduino.pinMode(0, ArduinoFirmata.INPUT);
			thread.start();
		} catch (IOException e) {
			e.printStackTrace();
			finish();
		} catch (InterruptedException e) {
			e.printStackTrace();
			finish();
		}
    }
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();
        if (id == R.id.action_settings) {
            return true;
        }
        return super.onOptionsItemSelected(item);
    }
    
   
    
    class Button_Listener implements OnClickListener {

    	  public Button_Listener(MainActivity activity) {

    	  }
    	  @Override
		public void onClick(View view) {
			if (!timerHasStarted) {
				CountDownTimer.start();
				MySensor.onResume();

				timerHasStarted = true;
				startB.setText("RESET ME!");
			} else {
				CountDownTimer.cancel();
				MySensor.onPause();
				timerHasStarted = false;
				startB.setText("Start Counting... 60 Sec.");

				// arduino.close();

			}
		}
	}
    public class TestCounting extends CountDownTimer{
    	int Count = 0;

		public TestCounting(long startTime, long interval) {
			super(startTime, interval);
		}
		@Override
		public void onFinish(){
			TimeView.setText("Time's Up");
			ElapsedView.setText("Time Elapsed:" + String.valueOf(startTime));
			CountAccel.setText("Upate Accel "+ MyCountingSensorUpdateRate.GetCounting("TYPE_ACCELEROMETER") +" Times per "+startTime+" ms");
			CountOrien.setText("Upate Orien "+  MyCountingSensorUpdateRate.GetCounting("TYPE_ORIENTATION") +" Times per "+startTime+" ms");
			MyCountingSensorUpdateRate.Clear();
			MySensor.onPause();
		}
		@Override
		public void onTick(long millisUntillFinished){
			TimeView.setText("Time remain : "+ millisUntillFinished);
			timeElapsed = startTime - millisUntillFinished;
			ElapsedView.setText("Time Elapsed : " + String.valueOf(timeElapsed));
			if(Count%10==1){
			arduino.digitalWrite(13, ArduinoBlink); // on board LED
			ArduinoBlink = ! ArduinoBlink;
			}
			Count++;
		}
    	
    
    }
 /* 下略 Sensor 部分*/

}

看起來是不是很容易呢?

主要就是 analogRead 以及 digitalRead 這兩個method,

但是! 人生中的『但是』常常給我們驚喜無窮 !

這樣寫是讀不出資料的,編譯 / 安裝 / 測試 都不會發生 crash 跟跳 error , 沒資料就是沒資料,彷彿 arduino input 被蓋上國防布一般...

筆者我針對這兩個method 曾奮鬥了 4 個鐘頭還是一頭霧水 XD

先賣個關子,下回再一步一步解決這個奇怪的問題

我們明天見


上一篇
x86 android 設備與外部硬體溝通研究 - Android USB -3 (PWM) (20/30)
下一篇
x86 android 設備與外部硬體溝通研究 - ArduinoFirmata.java (22/30)
系列文
x86 android 設備與外部硬體溝通研究30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言